package kpi.java_training.testing;

import kpi.java_training.testing.commands.CommandList;
import kpi.java_training.testing.db.StatisticsManager;
import kpi.java_training.testing.questions.QuestionList;
import kpi.java_training.testing.services.LanguageServices;
import kpi.java_training.testing.services.StringServices;
import kpi.java_training.testing.user.UserData;
import kpi.java_training.testing.userInterface.Input;
import kpi.java_training.testing.userInterface.Output;

/**
 * Class performs testing of a userData on module 1
 */
public class Testing {
    protected QuestionList questions;
    protected CommandList commands;
    protected UserData userData;
    protected Input input;
    protected Output output;
    protected int currentQuestion;
    protected int correctResults;
    protected boolean breakFlag;

    public Testing(UserData userData) {
        input = new Input();
        output = new Output();
        this.userData = userData;
        questions = null;
        commands = new CommandList();
        commands.addStandardCommands(this);
        breakFlag = false;
    }

    public void startTesting() {
        final String CONTINUE_CHOICE = "1";
        final String NEW_CHOICE = "2";
        String str = "";
        if (userData.userDataExists()) {
            output.showLine("Found saved test. Choose action:\n1. Continue saved test.\n2. Start new test");
            while (!str.equals(CONTINUE_CHOICE) && !str.equals(NEW_CHOICE)) {
                str = input.getString();
            }
        }
        if (str.equals(CONTINUE_CHOICE)) {
            questions = userData.getSavedQuestions("rt");
            setStep(userData.getSavedAnswers(questions));
        } else {
            questions = userData.getNewQuestions();
        }
        test();
    }

    private void test() {
        correctResults = 0;
        output.showLine("Starting test.");
        breakFlag = false;
        while (currentQuestion < questions.length()) {
            String answer = askQuestion(currentQuestion);
            String message = commands.executeCommand(answer);

            if (!message.equals("")) {
                output.showLine(String.format("Command found.\n%s", message));
            } else {
                questions.setQuestionAnswer(answer);
                currentQuestion++;
            }
            if (breakFlag) {
                return;
            }
        }
        correctResults = questions.getScore();
        printResults();

        StatisticsManager statisticsManager = new StatisticsManager();
        statisticsManager.updateStatistics(userData.getUserName(), questions.length(), correctResults);
    }

    public void endTest() {
        breakFlag = true;
    }

    protected String askQuestion(int currentQuestion) {
        output.showLine(String.format("Question %d from %d. Answer the question or type command.", currentQuestion + 1, questions.length()));
        output.showLine(questions.getQuestionMessage());
        return input.getString();
    }

    public void stepBack() {
        if (currentQuestion > 0) {
            currentQuestion--;
        }
    }

    protected void setStep(int step) {
        if (step < 0) {
            step = 0;
        } else if (step >= questions.length()) {
            step = questions.length();
        }
        currentQuestion = step;
    }

    public void saveSession() {
        userData.saveSession(StringServices.makeString(questions.getQuestionsSaveData(),
                questions.getAnswersSaveData(currentQuestion)));
    }

    public void printResults() {
        output.showLine(String.format("Your result is: %d correct %s out of %d.", correctResults,
                LanguageServices.getAnswerString(correctResults), questions.length()));
    }
}
